import { computePosition, shift } from "@floating-ui/dom";
import {
  EpEffect,
  default as EpView,
  modRoutingEP,
} from "./ChartsPlay/mod-routing.mjs";
import {
  default as DgView,
  modRoutingDG,
} from "./DeveloperGuide/mod-routing.mjs";
import { default as HnView, modRoutingHN } from "./HtmlNative/index.js";
import IndexView from "./index-view.html";
// eslint-disable-next-line import/namespace
import { useChangeCheck } from "#lit-comp/example/rxjs-use-change-check";
import { combRouter, defineRouter } from "@/routers/tools.mjs";

// #Effect
// import { modRoutingDG } from "./DeveloperGuide/mod.mjs";
const indexState = defineRouter({
  name: "index",
  url: "/",
  /**
   * @implements {ng.IController}
   */
  controller: class IndexCtrl {
    static $inject = ["$scope", "$element", "$document"];

    dataInst = Array.from({ length: 1000 }, (_, i) => ({
      i,
      name: `name-${i}`,
    }));

    /**
     * @param {ng.IScope} $scope
     * @param {ng.IAugmentedJQuery & HTMLElement} $element
     * @param {ng.IDocumentService & Element} $document
     */
    constructor($scope, $element, $document) {
      this.$scope = $scope;
      this.$element = $element;
      this.$document = $document;
      this.showNav = false;
      this.showNav2 = false;
    }

    $onInit() {
      // computePosition(this.$document, this.$element, {
      //   middleware: [shift()],
      // });
    }

    // real onMounted
    $postLink() {
      // console.log("postLink");
    }

    /**
     * @param {Event} e
     */
    openNav(e) {
      e.stopPropagation();
      this.showNav = !this.showNav;
    }

    /**
     * @param {Event} e
     */
    openNav2(e) {
      e.stopPropagation();
      this.showNav2 = !this.showNav2;
    }
  },
  controllerAs: "IndexCtrl",
  template: /* HTML */ html`
    <h3 data-inspector="src/view/root.mjs">
      hello world! <strong class="">NG-V1</strong>
    </h3>
    <!-- <nav-l3>
      <template #="showNav2">
        <nav-l3 showNav="showNav2"></nav-l3>
      </template>
    </nav-l3> -->
    ${IndexView}
    <hr />
    <h2>rapid jumping</h2>
    <h4 class="text-center">origin</h4>
    <nav class="main-nav justify-center">
      <div><a href="/#!/dg/co/fc">/dg/co/fc</a></div>
    </nav>
    <h4 class="text-center">Bootstrap</h4>
    <nav class="main-nav justify-center">
      <div><a ng-href="/#!/dg/bu/hs">/dg/bu/hs</a></div>
      <div><a ng-href="/#!/dg/bu/tb">/dg/bu/tb</a></div>
      <div><a ng-href="/#!/dg/bu/fb">/dg/bu/fb</a></div>
      <div><a ng-href="/#!/dg/bu/bdw">/dg/bu/bdw</a></div>
      <div><a ng-href="/#!/dg/bb/compile-link">/dg/bb/compile-link</a></div>
    </nav>
    <h4 class="text-center">UI Bootstrap</h4>
    <nav class="main-nav justify-center">
      <div><a ng-href="/#!/dg/uib/modal">/dg/uib/modal</a></div>
      <div><a ng-href="/#!/dg/uib/dropdown">/dg/uib/dropdown</a></div>
      <div>
        <a ng-href="/#!/dg/uib/dropdown-modal">/dg/uib/dropdown-modal</a>
      </div>
    </nav>
    <div
      ui-scroll-viewport
      class="viewport viewport-height-fixed"
      id="viewport-adapter1"
    >
      <!-- <div
        class="item"
        ui-scroll="item in datasource"
        adapter="firstListAdapter"
        is-loading="isLoadingOnScope"
        buffer-size="5"
      >
        {{item.content}}
      </div> -->
    </div>
  `,
});
const indexSlashState = defineRouter({
  name: "index_slash",
  url: "/index",
  redirectTo: "/",
});
// about 只是占位的
const aboutState = defineRouter({
  name: "about-lit",
  url: "/about-lit",
  template: /* HTML */ html`
    <p>This demo shows how updates flow down a tree of Lit elements.</p>
    <p>
      In Lit, only elements whose properties ave changed will re-render.
      Elements whose properties have not changed will no re-render, even when
      their parent re-renders.
    </p>
    <p>
      In this demo we have a tree of elements, with two properties that are
      passed down the tree with property bindings. <code>baseValue</code> is
      passed to both the left and right children. <code>rightValue</code> is
      passed to only the right child.
    </p>
    <p>
      The elements display the sum of <code>baseValue</code> and
      <code>rightValue</code>. Elements flash on any <code>render()</code>
      call, whether or not any DOM is changed. Each element delays its render by
      100ms to show the updates flowing down the tree.
    </p>
    <p>
      You can see that incrementing <code>rightValue</code> only causes the
      right-most path of elements to update. Re-rendering an element does not
      cause all of its children to re-render.
    </p>
    <update-demo></update-demo>
    <p>
      This pruning of the update path happens because of a simple value change
      check in the reactive property setters. Similar setter logic can be
      implemented by any web component, and trees of mixed components will
      collectively exhibit the update path pruning behavior. No central logic is
      necessary.
    </p>
  `,
});

const cvState = defineRouter({
  name: "cv",
  url: "/cv",
  template: /* HTML */ html` <cv-resume></cv-resume> `,
});
const cv2State = defineRouter({
  name: "cv2",
  url: "/cv2",
  template: /* HTML */ html` <cv-resume-two></cv-resume-two> `,
});

const dgStates = [
  combRouter(DgView, {
    name: "dg",
    url: "/dg",
  }),
  ...modRoutingDG,
];

const epStates = [
  combRouter(EpView, {
    name: "ep",
    url: "/ep",
  }),
  ...modRoutingEP,
];
__App__ && EpEffect(__App__);

const hnStates = [
  combRouter(HnView, {
    name: "hn",
    url: "/hn",
  }),
  ...modRoutingHN,
];

/**
 * @todo 使用 import()
 * @type {DefineRoute[]}
 */
export const rootViewRouting = [
  indexSlashState,
  indexState,
  aboutState,
  cvState,
  cv2State,
  ...dgStates,
  ...epStates,
  ...hnStates,
];

/**
 * @ngController
 * @implements {angular.IController}
 */
export class RootRoutingController {
  static $inject = [
    "$location",
    "$anchorScroll",
    "$rootScope",
    "$scope",
    "$element",
    "$attrs",
    "$transclude",
  ];

  /**
   * @param {ng.ILocationService} $location
   * @param {ng.IAnchorScrollService} $anchorScroll
   * @param {ng.IRootScopeService} $rootScope
   * @param {RootRoutingScope} $scope
   * @param {ng.IAugmentedJQuery} $element
   * @param {ng.IAttributes} $attrs
   * @param {ng.ITranscludeFunction} $transclude
   */
  constructor(
    $location,
    $anchorScroll,
    $rootScope,
    $scope,
    $element,
    $attrs,
    $transclude,
  ) {
    this.$location = $location.path("/");
    this.$rootScope = $rootScope;
    this.$anchorScroll = $anchorScroll;
    // component
    this.$scope = $scope;
    this.$element = $element;
    this.$attrs = $attrs;
    this.$transclude = $transclude;

    /**
     * @deprecated drop in next version
     * @private
     * @desc just input
     * @type {string | null}
     */
    this.sv = "__CONTRACTOR__";
  }

  /**
   * @type {{uisref: boolean, uiview: boolean }}
   */
  debug = {
    uisref: false,
    uiview: false,
  };

  /**
   * @format related path string
   * @type {string[]}
   */
  vr = rootViewRouting
    // filter root-route
    .filter((route) => !route.name.includes("."))
    .slice(1) // remove '/'
    .map((route) => route.name);

  $onInit() {
    // init scope data
    this.$scope.$path = "/";

    this.$scope.$on("$locationChangeStart", () => {
      this.$scope.$path = this.$location.path();
    });
    this.$scope.$watch("$path", (newValue, oldValue) => {
      if (newValue !== oldValue) {
        console.log(`path changed "${oldValue}" -> "${newValue}"`);
      }
    });

    // #__LOG__
    console.log(this.vr);

    this.$rootScope.$on("$viewContentLoaded", (e) => {
      /**
       * @type {number[]}
       */
      const scopeIdList = [];
      /**
       * @param {ng.IRootScopeService} scope
       * @returns {void}
       */
      function traceBackId(scope) {
        scopeIdList.push(scope.$id);
        if (scope.$parent) {
          traceBackId(scope.$parent);
        }
      }
      void traceBackId(e.targetScope);
      console.log("scopeIdList", e.targetScope);
      console.log("list", scopeIdList.join(" -> "));
    });
  }

  /**
   * @param {angular.IOnChangesObject} cObj
   */
  $onChanges(cObj) {
    // console.log("change", cObj);
  }

  $postLink() {
    const { currentStatus$ } = useChangeCheck(this.$element.find("input"));
    currentStatus$.subscribe((status) => {
      console.log("currentStatus$", status);
    });
  }

  handleClick() {
    console.log("RootRoutingController", this.$scope);
  }
}

console.count("reload");
if (import.meta.webpackHot) {
  import.meta.webpackHot.accept((err, ids) => {
    if (err) {
      console.error("import.meta.webpackHot.accept error", err);
    } else {
      console.log("import.meta.webpackHot.accept ids", ids);
    }
  });
}
